Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

199
Views
How to "remember" previously calculated values in an expensive recursive function in react?

Suppose I have a recursive callback such as this (but more complex):

const weightedFactorial = useCallback(n => {
  if (n === 0) {
    return 1;
  }

  return weight * n * weightedFactorial(n - 1);
},[weight]);

Is there a way to store previously calculated values, such that if the function is called on a repeated index, it is possible to skip the recursion?

const value1 = weightedFactorial(60) 
// Calculate recursively

const value2 = weightedFactorial(30) 
// This value should already be known 
// and the calculation should be skipped

I've tried to keep a state with known values but I seem to get stuck in a loop, probably because it needs to be a dependency of the callback,

const [knownValues, setKnownValues] = useState([{ n: 0, value: 1 }]);
const weightedFactorial = useCallback(n => {
  const known = knownValues.find(known => known.n === n);
  if (known?.value) {
    return known.value;
  }

  const newValue = weight * n * weightedFactorial(n - 1);
  setKnownValues(knownValues => [...knownValues, { n, value: newValue }]);
  return newValue;
},[knownValues, weight]);
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

The easiest way to store results for memoisation is a Map, or an array if your function parameter is a positive integer:

function FactorialExamples(props) {
  const results = [1];
  const factorial = n => {
    if (n in results) return results[n]; // also takes care of our base case n==0
    return results[n] = n * factorial(n-1);
  };
  
  return <p>
    5!: { factorial(5) }
    <br />
    10!: { factorial(10) }
  </p>;
}

This will work nicely and not compute factorials more than once if you call factorial multiple times. However, it will still redo the computation on every rendering of your function component. To persist the results across re-renders, move the results variable out of the function into the module scope, or put it inside a reference (that will be stored once per mounted component):

function Factorial(props) {
  const results = useRef([1]).current;

  const factorial = n => {
    if (n in results) return results[n];
    return results[n] = n * factorial(n-1);
  };

  return <p>
    {props.n}!: { factorial(props.n) }
  </p>;
}

function Demo() {
  const [value, setValue] = useState(0);
  return <div>
    <input type="number" value={value} onInput=(e => setValue(e.currentTarget.valueAsNumber)} min="0" />
    <Factorial n={value} />
  </div>;
}

But you have a more complicated case: the weightedFactorial also depends on a weight state, not just on its argument1. You could reset the reference every time the weight changes, but that's complicated and error-prone.

Instead, use an approach similar to your useCallback, that switches out the results store together with the "callback". Instead of useCallback, use useMemo and return a closure from it:

const weightedFactorial = useMemo(() => {
  const results = [1];
  return n => {
    if (n in results) return results[n]; 
    return weight * n * weightedFactorial(n - 1);
  };
}, [weight]);

1: Of course, you could just treat both weight and n as arguments, and use a standard approach for memoising functions with multiple arguments (see also here). Then the results could again be stored statically or in a reference.

about 4 years ago · Juan Pablo Isaza Report

0

You can use React.useMemo to calculate the value on the first render or when a dependency changes. But maybe you are referring to memoization so that a previously calculate value doesn't need other computation. https://www.30secondsofcode.org/js/s/memoize or https://www.digitalocean.com/community/tutorials/js-understanding-recursion

You can combine both useMemo and memoization to achieve what you need.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!